#include "Player.h"
#include "TextureCache.h"
#include "AnimatedSprite.h"
#include "Config.h"

bool operator<(Player::SpriteState left, Player::SpriteState right)
{
    if (left.m_action == right.m_action)
    {
        return left.m_facing < right.m_facing;
    }
    else
    {
        return left.m_action < right.m_action;
    }
}

Player::Player(sf::Int32 x, sf::Int32 y)
: m_spriteState()
, m_x(x)
, m_y(y)
, m_horizontalFacing(LEFT)
, m_sprites()
{
    initializeSprites();
}

Player::~Player()
{
    getRidOfSprites();
}

void Player::initializeSprites()
{
    m_sprites[SpriteState(MOVING, DOWN)] = new AnimatedSprite(TextureCache::GetInstance()->LoadTexture(Config::kTexturePath),
                                                              0, Config::kSpriteSize * 0,
                                                              Config::kSpriteSize, Config::kSpriteSize,
                                                              10, 3, true);

    m_sprites[SpriteState(MOVING, LEFT)] = new AnimatedSprite(TextureCache::GetInstance()->LoadTexture(Config::kTexturePath),
                                                              0, Config::kSpriteSize,
                                                              Config::kSpriteSize, Config::kSpriteSize,
                                                              10, 3, true);

    m_sprites[SpriteState(MOVING, RIGHT)] = new AnimatedSprite(TextureCache::GetInstance()->LoadTexture(Config::kTexturePath),
                                                               0, Config::kSpriteSize * 2,
                                                               Config::kSpriteSize, Config::kSpriteSize,
                                                               10, 3, true);

    m_sprites[SpriteState(MOVING, UP)] = new AnimatedSprite(TextureCache::GetInstance()->LoadTexture(Config::kTexturePath),
                                                            0, Config::kSpriteSize * 3,
                                                            Config::kSpriteSize, Config::kSpriteSize,
                                                            10, 3, true);

    m_sprites[SpriteState(STANDING, DOWN)] = new AnimatedSprite(TextureCache::GetInstance()->LoadTexture(Config::kTexturePath),
        32, Config::kSpriteSize * 0,
        Config::kSpriteSize, Config::kSpriteSize,
        10, 1, false);

    m_sprites[SpriteState(STANDING, LEFT)] = new AnimatedSprite(TextureCache::GetInstance()->LoadTexture(Config::kTexturePath),
        32, Config::kSpriteSize * 1,
        Config::kSpriteSize, Config::kSpriteSize,
        10, 1, false);

    m_sprites[SpriteState(STANDING, RIGHT)] = new AnimatedSprite(TextureCache::GetInstance()->LoadTexture(Config::kTexturePath),
        32, Config::kSpriteSize * 2,
        Config::kSpriteSize, Config::kSpriteSize,
        10, 1, false);

    m_sprites[SpriteState(STANDING, UP)] = new AnimatedSprite(TextureCache::GetInstance()->LoadTexture(Config::kTexturePath),
        32, Config::kSpriteSize * 3,
        Config::kSpriteSize, Config::kSpriteSize,
        10, 1, false);
}

void Player::getRidOfSprites()
{
    for (TSprites::iterator it = m_sprites.begin(); it != m_sprites.end(); ++it)
    {
        delete it->second;
    }
}

Player::SpriteState Player::getSpriteState() const
{
    return m_spriteState;
}

void Player::StartMovingLeft()
{
    m_spriteState.m_action = MOVING;
    m_spriteState.m_facing = LEFT;
}

void Player::StartMovingRight()
{
    m_spriteState.m_action = MOVING;
    m_spriteState.m_facing = RIGHT;
}

void Player::StartMovingUp()
{
    m_spriteState.m_action = MOVING;
    m_spriteState.m_facing = UP;
}

void Player::StartMovingDown()
{
    m_spriteState.m_action = MOVING;
    m_spriteState.m_facing = DOWN;
}

void Player::StopMoving()
{
    m_spriteState.m_action = STANDING;
}

void Player::Update(sf::Int32 deltaTime)
{
    SpriteState ss = getSpriteState();
    m_sprites[ss]->setPosition(sf::Vector2f(static_cast<float>(m_x), static_cast<float>(m_y)));
    m_sprites[ss]->Update(deltaTime);
}

void Player::Render(sf::RenderWindow& window)
{
    m_sprites[getSpriteState()]->Draw(window);
}
